﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using System.Web.Routing;
using JULONG.WEB.Library;

namespace YHWE.Web.Areas.manage.Models
{
    public class loginFilter : ActionFilterAttribute
    {
        //public string Message { get; set; }

        /// <summary>
        /// 黑名单表
        /// </summary>
        public List<routeForFilter> blacklist = new List<routeForFilter>();

        bool isBlacklist(RouteData dict)
        {
            var routeForFilter = new routeForFilter(dict);

            foreach (var item in blacklist)
            {
                if (item == routeForFilter)
                    return true;
            }

            return false;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)//在Action执行前执行  
        {
            //filterContext.HttpContext.Response.Write(@"<br />Before Action Excute" + "\t " + Message);
            //base.OnActionExecuting(filterContext);

            //得到路由信息
            var routeDict = filterContext.RouteData;

            //如果在黑名单内，则不执行
            if (isBlacklist(routeDict)) return;

            //如果已经登陆则跳出
            if (AccountClass.isLogin) return;

            Type controller = filterContext.Controller.GetType();
            string actionName = filterContext.ActionDescriptor.ActionName;
            var action = controller.GetMethods().FirstOrDefault(d => d.Name.ToLower() == actionName.ToLower());

            Type returnType = action == null ? null : action.ReturnType;

            //如果返回值是ActionResult
            if (returnType == typeof(ActionResult))
            {
                //生成返回的url
                //var reUrl = new System.Web.UI.Control().GetRouteUrl(routeDict);
                //得到请求URL
                var url = filterContext.HttpContext.Request.Path;

                //转向到登录界面
                string loginUrl = "/Home/login?url=" + url;

                //不能这么写
                //filterContext.HttpContext.Response.Redirect(loginUrl, true);
                filterContext.Result = new RedirectResult(loginUrl, true);
                return;
            }

            if (returnType == typeof(JsonResult))
            {
                //未写完
                filterContext.Result = new JsonResult();
                return;
            }

            filterContext.Result = myViewResult.notFound();
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)//在Action执行之后执行 
        {
            //输出到输出流中文字：After Action Excute xxx
            //filterContext.HttpContext.Response.Write(@"<br />After Action Excute" + "\t " + Message);
            //base.OnActionExecuted(filterContext);
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)//在Result执行之前   
        {
            //filterContext.HttpContext.Response.Write(@"<br />Before ViewResult Excute" + "\t " + Message);
            //base.OnResultExecuting(filterContext);
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)//在Result执行之后    
        {
            //filterContext.HttpContext.Response.Write(@"<br />After ViewResult Excute" + "\t " + Message);
            //base.OnResultExecuted(filterContext);
        }

        public class routeForFilter
        {
            public routeItem area { get; set; }
            public routeItem controller { get; set; }
            public routeItem action { get; set; }

            public routeForFilter()
            {

            }

            public routeForFilter(RouteData dict)
            {
                this.controller = dict.Values["controller"].ToTryString();
                this.action = dict.Values["action"].ToTryString();
                var area = dict.DataTokens;
                if (area.ContainsKey("area"))
                {
                    this.area = area["area"].ToTryString();
                }
                else
                {
                    this.area = new routeItem(null);
                }

            }

            /// <summary>
            /// 根据string 构造
            /// </summary>
            /// <param name="controller"></param>
            /// <param name="action"></param>
            /// <param name="area"></param>
            public routeForFilter(string action, string controller, string area = null)
            {
                this.controller = controller;
                this.action = action;
                this.area = area;
            }


            public override bool Equals(object obj)
            {
                return base.Equals(obj);
            }

            public override int GetHashCode()
            {
                return base.GetHashCode();
            }


            /// <summary>
            /// == 运算符重载
            /// </summary>
            /// <param name="r1"></param>
            /// <param name="r2"></param>
            /// <returns></returns>
            public static bool operator ==(routeForFilter left, routeForFilter right)
            {
                if (Equals(left, right))
                    return true;

                if (left.action != right.action)
                    return false;

                if (left.controller != right.controller)
                    return false;

                if (left.area != right.area)
                    return false;

                return true;
            }

            /// <summary>
            /// != 运算符重载
            /// </summary>
            /// <param name="r1"></param>
            /// <param name="r2"></param>
            /// <returns></returns>
            public static bool operator !=(routeForFilter left, routeForFilter right)
            {
                if (Equals(left, right))
                    return false;

                if (left.action != right.action)
                    return true;

                if (left.controller != right.controller)
                    return true;

                if (left.area != right.area)
                    return true;

                return false;
            }

        }


        public class routeItem
        {
            string _value;

            public string value
            {
                get
                {
                    return _value;
                }
                set
                {
                    _value = value;
                }
            }

            public routeItem(string value)
            {
                _value = value;
            }

            public override bool Equals(object obj)
            {
                return base.Equals(obj);
            }

            public override int GetHashCode()
            {
                return base.GetHashCode();
            }

            /// <summary>
            /// 等于号重载
            /// </summary>
            /// <param name="value"></param>
            /// <returns></returns>
            public static implicit operator routeItem(string value)
            {
                return new routeItem(value);
            }

            /// <summary>
            /// 等于号重载
            /// </summary>
            /// <param name="routeItem"></param>
            /// <returns></returns>
            public static implicit operator string(routeItem routeItem)
            {
                return routeItem._value;
            }

            /// <summary>
            /// == 运算符重载
            /// </summary>
            /// <param name="left"></param>
            /// <param name="right"></param>
            /// <returns></returns>
            public static bool operator ==(routeItem left, routeItem right)
            {
                if (Equals(left, right))
                    return true;

                if (left.value == "*")
                    return true;

                if (right.value == "*")
                    return true;

                if (String.Compare(left.value, right.value, true) == 0)
                    return true;

                return false;
            }


            /// <summary>
            /// != 运算符重载
            /// </summary>
            /// <param name="left"></param>
            /// <param name="right"></param>
            /// <returns></returns>
            public static bool operator !=(routeItem left, routeItem right)
            {
                if (Equals(left, right))
                    return false;

                if (left.value == "*")
                    return false;

                if (right.value == "*")
                    return false;

                if (String.Compare(left.value, right.value, true) == 0)
                    return false;

                return true;
            }

        }
    }
}
